/*
 *  Copyright (c) 2013 The CCP project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a Beijing Speedtong Information Technology Co.,Ltd license
 *  that can be found in the LICENSE file in the root of the web site.
 *
 *   http://www.cloopen.com
 *
 *  An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
package com.hz.friends.chat.Helper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.avos.avoscloud.AVException;
import com.avos.avoscloud.AVObject;
import com.avos.avoscloud.AVUser;
import com.hisun.phone.core.voice.CCPCall;
import com.hisun.phone.core.voice.Device;
import com.hisun.phone.core.voice.DeviceListener;
import com.hisun.phone.core.voice.listener.OnChatroomListener;
import com.hisun.phone.core.voice.listener.OnIMListener;
import com.hisun.phone.core.voice.model.CloopenReason;
import com.hisun.phone.core.voice.model.chatroom.Chatroom;
import com.hisun.phone.core.voice.model.chatroom.ChatroomMember;
import com.hisun.phone.core.voice.model.chatroom.ChatroomMsg;
import com.hisun.phone.core.voice.model.im.IMAttachedMsg;
import com.hisun.phone.core.voice.model.im.IMDismissGroupMsg;
import com.hisun.phone.core.voice.model.im.IMInviterMsg;
import com.hisun.phone.core.voice.model.im.IMJoinGroupMsg;
import com.hisun.phone.core.voice.model.im.IMProposerMsg;
import com.hisun.phone.core.voice.model.im.IMQuitGroupMsg;
import com.hisun.phone.core.voice.model.im.IMRemoveMemeberMsg;
import com.hisun.phone.core.voice.model.im.IMReplyJoinGroupMsg;
import com.hisun.phone.core.voice.model.im.IMTextMsg;
import com.hisun.phone.core.voice.model.im.InstanceMsg;
import com.hisun.phone.core.voice.model.setup.UserAgentConfig;
import com.hisun.phone.core.voice.util.Log4Util;
import com.hisun.phone.core.voice.util.SdkErrorCode;
import com.hz.friends.application.CustomApplication;
import com.hz.friends.chat.entity.IMChatMessage;
import com.hz.friends.serverrequest.ALCCPEngine;
import com.hz.friends.serverrequest.ALEngineConfig.CallBack;
import com.hz.friends.utils.MLog;

/**
 * VOIP Helper for Activity, it already has been did something important jobs
 * that activity just show state of ui by handler.
 * 
 * Before running the demo, you should be become a developer by CCP web site so
 * that you can get the main account and token, otherwise also see test info.
 * 
 * @version 1.0.0
 */
public class CCPHelper implements CCPCall.InitListener, DeviceListener,
		OnIMListener, OnChatroomListener {

	private final String TAG = this.getClass().getSimpleName();
	// our suggestion this context should be ApplicationContext
	private Context context;

	// invoked after created it
	private Device device;

	private RegistCallBack mCallback;

	public static final int SDK_NOTIFICATION = 99;
	public static final int ICON_LEVEL_ORANGE = 0;
	public static final int ICON_LEVEL_GREEN = 1;
	public static final int ICON_LEVEL_RED = 2;
	public static final int ICON_LEVEL_BLACK = 3;

	private static CCPHelper sInstance;

	/**
	 * 
	 * <p>
	 * Title: getInstance
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 * 
	 * @see CCPHelper#init(Context, Handler)
	 * @return
	 */
	public static CCPHelper getInstance() {
		if (sInstance == null) {
			sInstance = new CCPHelper(CustomApplication.getInstance());
		}
		return sInstance;
	}

	/**
	 * Constructs a new {@code VoiceHelper} instance.
	 * 
	 * @param context
	 * @see #Context
	 */
	private CCPHelper(Context context, RegistCallBack rcb) {
		this.context = context;
		this.mCallback = rcb;

	}

	/**
	 * Constructs a new {@code VoiceHelper} instance.
	 * 
	 * @param context
	 * @see #Context
	 */
	private CCPHelper(Context context) {
		this(context, null);
	}

	/**
	 * 
	 * @param rcb
	 */
	public void registerCCP(RegistCallBack rcb) {
		setRegistCallback(rcb);

		Log4Util.init(true);
		CCPCall.init(context, this);
		MLog.i(TAG, "CCPCallService registerCCP(RegistCallBack rcb)  init");

	}

	/**
	 * Callback this method when SDK init success.
	 * 
	 * Please note: you must write info that those remark start.
	 * 
	 * SDK init just once, but device can create more.
	 * 
	 * @see #onInitialized()
	 */
	@Override
	public void onInitialized() {
		try {
			createDevice();
		} catch (Exception e) {
			e.printStackTrace();
			// throw new RuntimeException(e);
			onError(e);
		}
	}

	/**
	 * 
	 * <p>
	 * Title: createDevice
	 * </p>
	 * <p>
	 * Description: modify by version 3.5
	 * </p>
	 * 
	 * @throws Exception
	 */
	private void createDevice() throws Exception {
		// //test 1
		// CCPConfig.Sub_Account = "0000000041c0731c0141c9abf78600b1";
		// CCPConfig.Sub_Token = "96f9ef79c6b347baa89bdb4c3ae2ae78";
		// CCPConfig.VoIP_ID = "80609900000001";
		// CCPConfig.VoIP_PWD = "30n7pa38";
		//
		//
		// //test 2
		// CCPConfig.Sub_Account = "0000000041c0731c0141c9abf78b00b2";
		// CCPConfig.Sub_Token = "2d531b3488da427c9890370129acbb24";
		// CCPConfig.VoIP_ID = "80609900000002";
		// CCPConfig.VoIP_PWD = "ojd37rmp";
		//
		// //test 3 CHESHI2
		// CCPConfig.Sub_Account = "377dcab73bd611e4823dac853d9f54f2";
		// CCPConfig.Sub_Token = "75ee04ae85b626ab45940209dcfdea03";
		// CCPConfig.VoIP_ID = "82005900000015";
		// CCPConfig.VoIP_PWD = "RSCjzIHc";

		// 封装参数
		Map<String, String> params = new HashMap<String, String>();
		// * REST服务器地址
		params.put(UserAgentConfig.KEY_IP, CCPConfig.REST_SERVER_ADDRESS);
		// * REST服务器端口
		params.put(UserAgentConfig.KEY_PORT, CCPConfig.REST_SERVER_PORT);
		// * VOIP账号 , 可以填入CCP网站Demo管理中的测试VOIP账号信息
		params.put(UserAgentConfig.KEY_SID, CCPConfig.VoIP_ID);
		// * VOIP账号密码, 可以填入CCP网站Demo管理中的测试VOIP账号密码
		params.put(UserAgentConfig.KEY_PWD, CCPConfig.VoIP_PWD);
		// * 子账号, 可以填入CCP网站Demo管理中的测试子账号信息
		params.put(UserAgentConfig.KEY_SUBID, CCPConfig.Sub_Account);
		// * 子账号密码, 可以填入CCP网站Demo管理中的测试子账号密码
		params.put(UserAgentConfig.KEY_SUBPWD, CCPConfig.Sub_Token);
		// User-Agent
		params.put(UserAgentConfig.KEY_UA, CustomApplication.getInstance()
				.getUser_Agent());

		// 创建Device
		device = CCPCall.createDevice(this /* DeviceListener */, params);
		// device.setOnIMListener(this);
		device.setOnChatroomListener(this);

		// device.setNativeLog(true);//
		MLog.i(TAG, "[createDevice] sdk init success. done");
	}

	/**
	 * Callback this method when sdk init errors.
	 * 
	 * @param exception
	 *            SDK init execption
	 * @see CCPHelper#init(Context, Handler)
	 */
	@Override
	public void onError(Exception exception) {
		CCPCall.shutdown();
		MLog.i(TAG, "[onError] " + "SDK init error , " + exception.getMessage());
		if (mCallback != null) {
			mCallback.onRegistResult(WHAT_INIT_ERROR,
					"SDK初始化错误, " + exception.getMessage());
		}

	}

	/**
	 * handler 转换消息id
	 */
	public static final int WHAT_ON_CONNECT = 0x2000; // 连接成功
	public static final int WHAT_ON_DISCONNECT = 0x2001; // 连接失败
	public static final int WHAT_INIT_ERROR = 0x200A; // 初始化错误
	public static final int WHAT_ON_CALL_ALERTING = 0x2002;
	public static final int WHAT_ON_CALL_ANSWERED = 0x2003;
	public static final int WHAT_ON_CALL_PAUSED = 0x2004;
	public static final int WHAT_ON_CALL_PAUSED_REMOTE = 0x2005;
	public static final int WHAT_ON_CALL_RELEASED = 0x2006;
	public static final int WHAT_ON_CALL_PROCEEDING = 0x2007;
	public static final int WHAT_ON_CALL_TRANSFERED = 0x2008;
	public static final int WHAT_ON_CALL_MAKECALL_FAILED = 0x2009;
	public static final int WHAT_ON_CALL_BACKING = 0x201B;

	// 2013.3.11
	public static final int WHAT_ON_NEW_VOICE = 0x201C;
	public static final int WHAT_ON_AMPLITUDE = 0x201D; // 录音振幅
	public static final int WHAT_ON_RECODE_TIMEOUT = 0x202A; // 录音超时
	public static final int WHAT_ON_UPLOAD_VOICE_RES = 0x202B;
	public static final int WHAT_ON_PLAY_VOICE_FINSHING = 0x202C; // 声音播放完

	public static final int WHAT_ON_INTERPHONE = 0x203A;
	public static final int WHAT_ON_CONTROL_MIC = 0x203B;
	public static final int WHAT_ON_RELEASE_MIC = 0x203C;
	public static final int WHAT_ON_INTERPHONE_MEMBERS = 0x203D;
	public static final int WHAT_ON_INTERPHONE_SIP_MESSAGE = 0x203E;
	public static final int WHAT_ON_DIMISS_DIALOG = 0x204A;;

	public static final int WHAT_ON_REQUEST_MIC_CONTROL = 0x204C;
	public static final int WHAT_ON_RELESE_MIC_CONTROL = 0x204D;
	public static final int WHAT_ON_PLAY_MUSIC = 0x204E;
	public static final int WHAT_ON_STOP_MUSIC = 0x204F;

	public static final int WHAT_ON_VERIFY_CODE_SUCCESS = 0x205A;
	public static final int WHAT_ON_VERIFY_CODE_FAILED = 0x205B;

	// Chatroom
	public static final int WHAT_ON_CHATROOM_SIP_MESSAGE = 0x205C; // 收到聊天室消息
	public static final int WHAT_ON_CHATROOM_MEMBERS = 0x205D; // 获取聊天室成员
	public static final int WHAT_ON_CHATROOM_LIST = 0x205E;// 获取聊天室列表
	public static final int WHAT_ON_CHATROOM = 0x206A; // 聊天室状态、创建或者加入聊天室的状态。
	public static final int WHAT_ON_CHATROOM_INVITE = 0x206B; // 邀请加入聊天室
	public static final int WHAT_ON_MIKE_ANIM = 0x206C;
	public static final int WHAT_ON_CNETER_ANIM = 0x206D;
	public static final int WHAT_ON_VERIFY_CODE = 0x206E;
	public static final int WHAT_ON_CHATROOMING = 0x207A;
	public static final int WHAT_ON_CHATROOM_KICKMEMBER = 0x207B;// 踢出成员
	public static final int WHAT_ON_SET_MEMBER_SPEAK = 0x207C;

	// IM
	public static final int WHAT_ON_SEND_MEDIAMSG_RES = 0x208A;
	public static final int WHAT_ON_NEW_MEDIAMSG = 0x208B;
	public static final int WHAT_ON_RECEIVE_SYSTEM_EVENTS = 0x208C; // 系统事件回调
																	// 来电话

	public static final int WHAT_ON_CALL_TRANSFERSTATESUCCEED = 0x208d;

	/**
	 * handler for update activity
	 */
	private Handler handler;

	/**
	 * set handler.
	 * 
	 * @param handler
	 *            activity handler
	 */
	public void setHandler(final Handler handler) {
		this.handler = handler;
	}

	/**
	 * get the device.
	 * 
	 * @return the device
	 */
	public Device getDevice() {
		return device;
	}

	long t = 0;
	private long currentTime = 0;

	/**
	 * send object to activity by handler.
	 * 
	 * @param what
	 *            message id of handler
	 * @param obj
	 *            message of handler
	 */
	private void sendTarget(int what, Object obj) {
		t = System.currentTimeMillis();
		// for kinds of mobile phones
		while (handler == null && (System.currentTimeMillis() - t < 3200)) {
			MLog.i(TAG,
					"[VoiceHelper] handler is null, activity maybe destory, wait...");
			try {
				Thread.sleep(80L);
			} catch (InterruptedException e) {
			}
		}

		if (handler == null) {
			MLog.i(TAG, "[VoiceHelper] handler is null, need adapter it.");
			return;
		}

		Message msg = Message.obtain(handler);
		msg.what = what;
		msg.obj = obj;
		msg.sendToTarget();
	}

	/***********************************************************************************
	 * * Following are DeviceListener Callback Methods * *
	 ************************************************************************************/

	/**
	 * Callback this method when register successful, developer can show
	 * notification to user.
	 */
	@Override
	public void onConnected() {
		MLog.i(TAG,
				"[onConnected] Connected on the cloud communication platform success..");
		if (mCallback != null) {
			mCallback.onRegistResult(WHAT_ON_CONNECT,
					"Connected on the cloud communication platform success");
			//接管IM
			ALCCPEngine.defauleEngine();
			return;
		}
		//接管IM
		ALCCPEngine.defauleEngine();
		this.context
				.sendBroadcast(new Intent(CCPIntentUtils.INTENT_CONNECT_CCP));
	}

	/**
	 * Callback this method when register failed, developer can show hint to
	 * user.
	 * 
	 * @param reason
	 *            register failed reason
	 */
	@Override
	public void onDisconnect(Reason reason) {

		if (mCallback != null) {
			mCallback.onRegistResult(WHAT_ON_DISCONNECT, reason.toString());
			return;
		}

		if (reason == Reason.KICKEDOFF) { // 踢掉
			MLog.i(TAG, "Login account in other places.");
			this.context.sendBroadcast(new Intent(
					CCPIntentUtils.INTENT_KICKEDOFF));
			return;
		}

		if (reason == Reason.INVALIDPROXY) { // 无效的代理
			MLog.i(TAG, reason.getValue() + " INVALIDPROXY");
			this.context.sendBroadcast(new Intent(
					CCPIntentUtils.INTENT_INVALIDPROXY));
			return;
		}
		if (currentTime == 0
				|| System.currentTimeMillis() - currentTime > 5 * 60 * 1000)// 超过5分钟提示
		{
			this.context.sendBroadcast(new Intent(
					CCPIntentUtils.INTENT_DISCONNECT_CCP));
			currentTime = System.currentTimeMillis();
		}
		MLog.i(TAG,
				"[VoiceHelper - onDisconnect]Can't connect the cloud communication platform"
						+ ", please check whether the network connection,");
	}

	public void release() {
		this.context = null;
		this.device = null;
		this.handler = null;

		sInstance = null;
	}

	/**********************************************************************
	 * voice message *
	 **********************************************************************/
	// 播放录音结束回调
	@Override
	public void onFinishedPlaying() {
		// Bundle b = new Bundle();
		// sendTarget(WHAT_ON_PLAY_VOICE_FINSHING, b);
		//
		// context.sendBroadcast(new Intent(
		// CCPIntentUtils.INTENT_VOICE_PALY_COMPLETE));
	}

	// 录音振幅回调
	@Override
	public void onRecordingAmplitude(double amplitude) {
		// Bundle b = new Bundle();
		// b.putDouble(Device.VOICE_AMPLITUDE, amplitude);
		// sendTarget(WHAT_ON_AMPLITUDE, b);

	}

	// 录音超时回调
	@Override
	public void onRecordingTimeOut(long mills) {
		// Bundle b = new Bundle();
		// b.putLong("mills", mills);
		// sendTarget(WHAT_ON_RECODE_TIMEOUT, b);

	}

	// 聊天室状态回调 创建或者加入聊天室的状态
	@Override
	public void onChatroomState(CloopenReason reason, String confNo) {
		MLog.i(TAG, "[onChatRoomState ] reason " + reason + " , confNo "
				+ confNo);
		showToastMessage(reason);
		Bundle b = new Bundle();
		b.putInt(Device.REASON, reason.getReasonCode());
		b.putString(Device.CONFNO, confNo);
		sendTarget(WHAT_ON_CHATROOM, b);
	}

	/**
	 * 功能：连接云通讯平台成功后，通知是否有人加入、退出、被踢出和解散等。
	 * 该API是业务层面消息回调函数，根据业务类型，来传递不同的子类业务对象，从而达到通过该函数控制不同通知的目的
	 * 
	 * @param msg
	 */
	@Override
	public void onReceiveChatroomMsg(ChatroomMsg msg) {
		MLog.i(TAG, "[onReceiveChatRoomMsg ] Receive Chat Room message  , id :"
				+ msg.getRoomNo());
		Bundle b = new Bundle();
		b.putSerializable(Device.CHATROOM_MSG, msg);
		sendTarget(WHAT_ON_CHATROOM_SIP_MESSAGE, b);
	}

	// 获取聊天室成员
	@Override
	public void onChatroomMembers(CloopenReason reason,
			List<ChatroomMember> member) {
		MLog.i(TAG, "[onChatRoomMembers ] on Chat Room  members that .. "
				+ member);
		showToastMessage(reason);
		Bundle b = new Bundle();
		b.putSerializable(Device.CHATROOM_MEMBERS,
				(ArrayList<ChatroomMember>) member);
		sendTarget(WHAT_ON_CHATROOM_MEMBERS, b);
	}

	// 邀请加入聊天室
	@Override
	public void onChatroomInviteMembers(CloopenReason reason, String confNo) {
		MLog.i(TAG, "[onChatRoomInvite ] reason " + reason + " , confNo "
				+ confNo);
		showToastMessage(reason);
		Bundle b = new Bundle();
		b.putInt(Device.REASON, reason.getReasonCode());
		b.putString(Device.CONFNO, confNo);
		sendTarget(WHAT_ON_CHATROOM_INVITE, b);
	}

	// 获取聊天室列表， 获取聊天室列表
	@Override
	public void onChatrooms(CloopenReason reason, List<Chatroom> chatRoomList) {
		MLog.i(TAG, "[onChatrooms ] on Chat Room  chatrooms that .. "
				+ chatRoomList);
		showToastMessage(reason);
		Bundle b = new Bundle();
		b.putSerializable(Device.CHATROOM_LIST,
				(ArrayList<Chatroom>) chatRoomList);
		sendTarget(WHAT_ON_CHATROOM_LIST, b);

	}

	// 发送IM消息回调
	@Override
	public void onSendInstanceMessage(CloopenReason reason, InstanceMsg data) {
		MLog.i(TAG,
				"[onSendInstanceMessage ] on send Instance Message that reason .. "
						+ reason);
		showToastMessage(reason);
		if (data == null) {
			return;
		}
		int msgType = -1;
		try {
			if (!reason.isError()) { // 发送成功
				msgType = IMChatMessage.STATE_IM_SEND_SUCCESS;
			} else {// 失败
				if (reason.getReasonCode() != 230007) {
					msgType = IMChatMessage.STATE_IM_SEND_FAILED;
				}
			}

			if (msgType != -1) {
				String messageId = null;
				;
				if (data instanceof IMTextMsg) {
					messageId = ((IMTextMsg) data).getMsgId();
				} else if (data instanceof IMAttachedMsg) {
					messageId = ((IMAttachedMsg) data).getMsgId();
				}
				// CCPSqliteManager.getInstance()
				// .updateIMMessageSendStatusByMessageId(messageId,
				// msgType);
			}
		} catch (Exception e) {
			e.printStackTrace();
			//
		}
		Bundle b = new Bundle();
		b.putInt(Device.REASON, reason.getReasonCode());
		b.putInt("msgType", msgType);
		b.putSerializable(Device.MEDIA_MESSAGE, data);
		sendTarget(WHAT_ON_SEND_MEDIAMSG_RES, b);
	}

	// 下载IM附件回调
	@Override
	public void onDownloadAttached(CloopenReason reason, String fileName) {
		// untodo
	}

	// 收到InstanceMessage消息
	@Override
	public void onReceiveInstanceMessage(InstanceMsg msg) {
		MLog.i(TAG, "[onReceiveInstanceMessage ] " + msg.getClass().getName());
		try {

			boolean isNewMessageVibrate = true;
			if (msg != null) {
				if (msg instanceof IMAttachedMsg || msg instanceof IMTextMsg) {
					if (msg instanceof IMAttachedMsg) {

					} else if (msg instanceof IMTextMsg) {
						IMTextMsg aMsg = (IMTextMsg) msg;
						String sender = aMsg.getSender();
						String message = aMsg.getMessage();
						String receiver = aMsg.getReceiver();

						if (TextUtils.isEmpty(sender)
								|| TextUtils.isEmpty(message)
								|| TextUtils.isEmpty(receiver)) {
							return;
						}

						// if (CCPConfig.VoIP_ID.equals(sender)) {
						// return;
						// }

						String contactId = "";
						if (CCPConfig.VoIP_ID.equals(receiver)) {
							// not group message
							contactId = sender;
						} else {
							// group
							contactId = receiver;
						}

//						IMChatMessage chatMessageDetail = IMChatMessage
//								.getGroupItemMessageReceived(aMsg.getMsgId(),
//										IMChatMessage.MessageType.TXT,
//										contactId, sender);
//						chatMessageDetail.setMessageContent(message);
//						chatMessageDetail.setDateCreated(aMsg.getDateCreated());
						// chatMessageDetail.setUserData(aMsg.getUserData());

						// CCPSqliteManager.getInstance().insertIMMessage(
						// chatMessageDetail);
						Intent intent = new Intent(
								CCPIntentUtils.INTENT_IM_RECIVE);
						intent.putExtra("msg", msg);
						// intent.putExtra(GroupBaseActivity.KEY_GROUP_ID,
						// contactId);
						context.sendBroadcast(intent);

					}

				} else if (msg instanceof IMInviterMsg) {
					// Received the invitation to join the group
					IMInviterMsg imInviterMsg = (IMInviterMsg) msg;
					MLog.i(TAG,
							"[VoiceHelper - onReceiveInstanceMessage ] Receive invitation to join the group ,that amdin "
									+ imInviterMsg.getAdmin()
									+ " , and group id :"
									+ imInviterMsg.getGroupId());
					// CCPSqliteManager.getInstance().insertNoticeMessage(msg,
					// IMSystemMessage.SYSTEM_TYPE_INVITE_JOIN);
					Intent intent = new Intent(
							CCPIntentUtils.INTENT_RECEIVE_SYSTEM_MESSAGE);
					context.sendBroadcast(intent);
				} else if (msg instanceof IMJoinGroupMsg) {

					// The receipt of the application to join the group
					IMJoinGroupMsg imJoinMsg = (IMJoinGroupMsg) msg;
					MLog.i(TAG,
							"[VoiceHelper - onReceiveInstanceMessage ] Receive join message that Joiner "
									+ imJoinMsg.getProposer()
									+ " , and group id :"
									+ imJoinMsg.getGroupId());
					// CCPSqliteManager
					// .getInstance()
					// .insertNoticeMessage(
					// msg,
					// IMSystemMessage.SYSTEM_TYPE_APPLY_JOIN_UNVALIDATION);
					Intent intent = new Intent(
							CCPIntentUtils.INTENT_RECEIVE_SYSTEM_MESSAGE);
					context.sendBroadcast(intent);

					// BUG ..
				} else if (msg instanceof IMProposerMsg) {// 申请加入群消息

					// The receipt of the application to join the group

					IMProposerMsg imProposerMsg = (IMProposerMsg) msg;
					MLog.i(TAG,
							"[VoiceHelper - onReceiveInstanceMessage ] Receive proposer message that Proposer "
									+ imProposerMsg.getProposer()
									+ " , and group id :"
									+ imProposerMsg.getGroupId());
					// CCPSqliteManager.getInstance().insertNoticeMessage(msg,
					// IMSystemMessage.SYSTEM_TYPE_APPLY_JOIN);
					Intent intent = new Intent(
							CCPIntentUtils.INTENT_RECEIVE_SYSTEM_MESSAGE);
					context.sendBroadcast(intent);
				} else if (msg instanceof IMRemoveMemeberMsg) { // 移除群成员消息
					// Remove group received system information
					IMRemoveMemeberMsg imrMemeberMsg = (IMRemoveMemeberMsg) msg;
					MLog.i(TAG,
							"[VoiceHelper - onReceiveInstanceMessage ] Received system information that "
									+ "remove from group  id "
									+ imrMemeberMsg.getGroupId());
					// CCPSqliteManager.getInstance().insertNoticeMessage(msg,
					// IMSystemMessage.SYSTEM_TYPE_REMOVE);
					Intent intent = new Intent(
							CCPIntentUtils.INTENT_REMOVE_FROM_GROUP);
					// intent.putExtra(GroupBaseActivity.KEY_GROUP_ID,
					// imrMemeberMsg.getGroupId());
					context.sendBroadcast(intent);
				} else if (msg instanceof IMReplyJoinGroupMsg) {
					// Remove group received system information
					IMReplyJoinGroupMsg imAcceptRejectMsg = (IMReplyJoinGroupMsg) msg;
					MLog.i(TAG,
							"[VoiceHelper - onReceiveInstanceMessage ] Received system information that "
									+ "reject or accept from group  id "
									+ imAcceptRejectMsg.getGroupId());
					// CCPSqliteManager.getInstance().insertNoticeMessage(msg,
					// IMSystemMessage.SYSTEM_TYPE_ACCEPT_OR_REJECT_JOIN);
					Intent intent = null;
					if ("0".equals(imAcceptRejectMsg.getConfirm())) {
						intent = new Intent(
								CCPIntentUtils.INTENT_JOIN_GROUP_SUCCESS);
						// intent.putExtra(GroupBaseActivity.KEY_GROUP_ID,
						// imAcceptRejectMsg.getGroupId());
					} else {
						intent = new Intent(
								CCPIntentUtils.INTENT_RECEIVE_SYSTEM_MESSAGE);
					}
					context.sendBroadcast(intent);
				} else if (msg instanceof IMDismissGroupMsg) {
					// The group manager dismiss this group..
					IMDismissGroupMsg imDismissGroupMsg = (IMDismissGroupMsg) msg;
					MLog.i(TAG,
							"[VoiceHelper - onReceiveInstanceMessage ] Received system information that "
									+ "group manager dismiss this group  id "
									+ imDismissGroupMsg.getGroupId());
					// CCPSqliteManager.getInstance().insertNoticeMessage(msg,
					// IMSystemMessage.SYSTEM_TYPE_GROUP_DISMISS);
					Intent intent = null;
					intent = new Intent(CCPIntentUtils.INTENT_REMOVE_FROM_GROUP);
					// intent.putExtra(GroupBaseActivity.KEY_GROUP_ID,
					// imDismissGroupMsg.getGroupId());
					context.sendBroadcast(intent);
				} else if (msg instanceof IMQuitGroupMsg) {
					// The group manager dismiss this group..
					IMQuitGroupMsg imQuitGroupMsg = (IMQuitGroupMsg) msg;
					MLog.i(TAG,
							"[VoiceHelper - onReceiveInstanceMessage ] Received system information that "
									+ "Members quit from a group id "
									+ imQuitGroupMsg.getGroupId());
					// CCPSqliteManager.getInstance().insertNoticeMessage(msg,
					// IMSystemMessage.SYSTEM_TYPE_GROUP_MEMBER_QUIT);
					Intent intent = null;
					intent = new Intent(
							CCPIntentUtils.INTENT_RECEIVE_SYSTEM_MESSAGE);
					// intent.putExtra(GroupBaseActivity.KEY_GROUP_ID,
					// imQuitGroupMsg.getGroupId());
					context.sendBroadcast(intent);
				}

				if (isNewMessageVibrate) {
					// CCPVibrateUtil.getInstace().doVibrate();
					// 震动
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onConfirmIntanceMessage(CloopenReason reason) {
		showToastMessage(reason);
	}

	// 解散聊天室回调
	@Override
	public void onChatroomDismiss(CloopenReason reason, String roomNo) {
		Intent intent = new Intent(CCPIntentUtils.INTENT_CHAT_ROOM_DISMISS);
		showToastMessage(reason);
		intent.putExtra("roomNo", roomNo);
		context.sendBroadcast(intent);
	}

	// 踢出成员回调
	@Override
	public void onChatroomRemoveMember(CloopenReason reason, String member) {
		showToastMessage(reason);
		Bundle b = new Bundle();
		b.putInt(Device.REASON, reason.getReasonCode());
		b.putString("kick_member", member);
		sendTarget(WHAT_ON_CHATROOM_KICKMEMBER, b);
	}

	@Override
	public void onFirewallPolicyEnabled() {
		Intent intent = new Intent(CCPIntentUtils.INTENT_P2P_ENABLED);
		context.sendBroadcast(intent);
	}

	/**
	 * Callback this method when networks changed. 系统事件回调
	 * 回调系统事件，如监听到系统来电则会通过此方法通知应用程序。
	 * 
	 * @param apn
	 *            mobile access point name
	 * @param ns
	 *            mobile network state
	 * 
	 * @version 3.5
	 */
	@Override
	public void onReceiveEvents(CCPEvents events/*
												 * , APN network, NetworkState
												 * ns
												 */) {
		MLog.i(TAG, "Receive CCP events , " + events);
		if (events == CCPEvents.SYSCallComing) {
			Bundle b = new Bundle();
			sendTarget(WHAT_ON_RECEIVE_SYSTEM_EVENTS, b);
		}
	}

	public void showToastMessage(CloopenReason reason) {
		if (reason != null && reason.isError()) {
			if (reason.getReasonCode() == 230007) {
				Toast.makeText(context,
						"语音发送被取消[" + reason.getReasonCode() + "]",
						Toast.LENGTH_SHORT).show();
				return;
			}

			if (reason.getReasonCode() == SdkErrorCode.SDK_FILE_NOTEXIST
					|| reason.getReasonCode() == SdkErrorCode.SDK_AMR_CANCLE) {
				return;
			}
			Toast.makeText(context,
					reason.getMessage() + "[" + reason.getReasonCode() + "]",
					Toast.LENGTH_SHORT).show();
		}
	}

	protected void finalize() {

		if (device != null) {
			device.release();
			device = null;
			sInstance = null;
		}
	}

	public void setRegistCallback(RegistCallBack rcb) {
		this.mCallback = rcb;
	}

	public interface RegistCallBack {
		/**
		 * WHAT_INIT_ERROR call back when regist over.
		 * 
		 * @param reason
		 *            {@link WHAT_INIT_ERROR} {@link WHAT_ON_CONNECT}
		 *            {@link WHAT_ON_DISCONNECT}
		 * @param msg
		 *            regist failed message
		 * 
		 * @see CCPHelper#WHAT_ON_CONNECT
		 * @see CCPHelper#WHAT_INIT_ERROR
		 * @see CCPHelper#WHAT_ON_DISCONNECT
		 */
		void onRegistResult(int reason, String msg);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.hisun.phone.core.voice.listener.OnChatroomListener#onSetMemberSpeakOpt
	 * (com.hisun.phone.core.voice.model.CloopenReason, java.lang.String) 禁言回调
	 */
	@Override
	public void onSetMemberSpeakOpt(CloopenReason reason, String member) {
		showToastMessage(reason);
		Bundle b = new Bundle();
		b.putInt(Device.REASON, reason.getReasonCode());
		b.putString("kick_member", member);
		sendTarget(WHAT_ON_SET_MEMBER_SPEAK, b);
	}
   
	private int countinit = 0;
	
	public void setCountInit(int times){
		countinit = times;
	}
	
	public void initVoipDevice() {
		countinit --;
		if(countinit <= 0)
			return;
		final AVUser user = AVUser.getCurrentUser();
		if (user == null)
			return;
		CCPConfig.Sub_Account = user.getString("subAccountSid");
		CCPConfig.Sub_Token = user.getString("subToken");
		CCPConfig.VoIP_ID = user.getString("voipAccount");
		CCPConfig.VoIP_PWD = user.getString("voipPwd");
		
        MLog.i(TAG, "==initVoipDevice CCPConfig.Sub_Account:"+CCPConfig.Sub_Account);
        MLog.i(TAG, "==initVoipDevice CCPConfig.Sub_Token:"+CCPConfig.Sub_Token);
        MLog.i(TAG, "==initVoipDevice CCPConfig.VoIP_ID:"+CCPConfig.VoIP_ID);
        MLog.i(TAG, "==initVoipDevice CCPConfig.VoIP_PWD:"+CCPConfig.VoIP_PWD);
       
		// 没有帐号
		if (CCPConfig.Sub_Account == null || CCPConfig.Sub_Token == null
				|| CCPConfig.VoIP_ID == null || CCPConfig.VoIP_PWD == null) {
			// 注册voip
			ALCCPEngine.defauleEngine().signUp(user,new CallBack() {
				@Override
				public void done(Object object, AVException avexception) {
                       MLog.i(TAG, "云通讯注册回调  object:"+object+" avexception:"+avexception);
                       if(avexception == null){
                    	   //刷新user voip 属性
                    	   ALCCPEngine.defauleEngine().logIn(user,new CallBack() {
							
							@Override
							public void done(Object object, AVException avexception) {
								initVoipDevice();
							}
						});
                       }else{
                    	   initVoipDevice();
                       }
				}
			});
			
		} else {// 有账号没初始化成功
			if (CCPHelper.getInstance().device == null)
				CCPHelper.getInstance().registerCCP(null);

		}
	}

}
